/********************************************************************************
*                                                                               *
* kwooka.cpp -- The kwooka app definition                                       *
*                                                                               *
* Copyright (c) Fengren Technology(Guangzhou) Co.LTD. All rights reserved.      *
*                                                                               *
********************************************************************************/

// ==========================================================================
// headers, declarations, constants
// ==========================================================================
#if defined(_DEBUG) && defined(WIN32)
#include <stdlib.h>
#include <crtdbg.h>
#endif

// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
    #pragma hdrstop
#endif
#ifndef WX_PRECOMP
    #include "wx/wx.h"
#endif
#include "kWooka.h"
#include "wx/statline.h"
#include "wx/wfstream.h"
#include "wx/filedlg.h"
#include "wx/stockitem.h"
#include "wx/dcbuffer.h"
#include "wx/tipwin.h"
#include "wx/metafile.h"
#include "wx/config.h"
#include <stdio.h>
#include "kWooka_aboutdlg.h"
#include "kWooka_ids.h"
#include "kWooka_frame.hpp"
#include "wx/dir.h"
#include "kWooka_perferences.hpp"
#include "kWookaSplashScreen.hpp"
#include <time.h>
// --------------------------------------------------------------------------
// resources
// --------------------------------------------------------------------------
#include "wx/xrc/xmlres.h"          // XRC XML resources

#if wxUSE_RIBBON
#include "wx/xrc/xh_ribbon.h"
#endif // wxUSE_RIBBON

#if wxUSE_AUI
#include "wx/xrc/xh_aui.h"
#include "wx/xrc/xh_auitoolb.h"
#endif // wxUSE_AUI


// --------------------------------------------------------------------------
// constants
// --------------------------------------------------------------------------

#include "kWookaProjectInfo.hpp"

// --------------------------------------------------------------------------
// event tables and other macros for wxWidgets
// --------------------------------------------------------------------------

#ifdef WIN32
void Privilege(TCHAR* pszPrivilege, BOOL bEnable);
void DisplayError(TCHAR* pszAPI, DWORD dwError);
#endif


void InitXmlResource();

#ifndef _DEBUG
// Create a new application object
wxIMPLEMENT_APP(kWookaApp);

#else

extern "C" int WINAPI WinMain(HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    wxCmdLineArgType lpCmdLine,
    int nCmdShow) 
{
    _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_DEBUG);
    _CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF);
    _CrtMemState s1, s2, s3;
    _CrtMemCheckpoint(&s1);
    int t = wxEntry(hInstance, hPrevInstance, lpCmdLine, nCmdShow);  
    _CrtMemCheckpoint(&s2);
    _CrtMemDifference(&s3, &s1, &s2);
    _CrtMemDumpStatistics(&s1);
    _CrtMemDumpStatistics(&s2);
    _CrtMemDumpStatistics(&s3);
    _CrtDumpMemoryLeaks();
    return t;
}

wxIMPLEMENT_APP_NO_MAIN(kWookaApp);

#endif

// ==========================================================================
// implementation
// ==========================================================================


// --------------------------------------------------------------------------
// LifeApp
// --------------------------------------------------------------------------
int kWookaApp::OnExit() {
	if (m_locale != NULL) {
		delete m_locale;
	}
    if (m_checker != NULL) {
        delete m_checker;
        m_checker = NULL;
    }
    if (m_mainFrame != NULL) {
        delete m_mainFrame;
        m_mainFrame = NULL;
    }

    // wxTranslations* trans = wxTranslations::Get();
    wxTranslations::Set(NULL);
    if (wxXmlResource::Get() != NULL) {
        wxXmlResource::Get()->ClearHandlers();
        wxXmlResource* res = wxXmlResource::Set(NULL);
        if (res != NULL) {
            delete res;
            res = NULL;
        }
    }
    // trans->SetLoader(NULL);
    // delete trans;
    wxUninitialize();

    wxImage::CleanUpHandlers();

	int excode = wxApp::OnExit();
    // wxApp::CleanUp();
    // _CrtDumpMemoryLeaks();
    return excode;
}
// 'Main program' equivalent: the program execution "starts" here
bool kWookaApp::OnInit()
{
    time_t now = 0;
    time(&now);
    char tmstr[64] = { '\0' };
    strftime(tmstr, sizeof(tmstr), "%Y-%m-%d %H:%M:%S", localtime(&now));
    printf("LocalTime: %s\n", tmstr);
    strftime(tmstr, sizeof(tmstr), "%Y-%m-%d %H:%M:%S", gmtime(&now));
    printf("GMTime: %s\n", tmstr);
    
    m_mainFrame = NULL;
    
    wxString store = wxT("root");
    FindKiloseedRootCert(store);

    wxInitAllImageHandlers();

    wxXmlResource::Get()->InitAllHandlers();
    
    InitXmlResource();

    
    m_checker = new wxSingleInstanceChecker;
    if (m_checker->IsAnotherRunning())
    {
#ifndef _DEBUG
        wxLogError(_("Another program instance is already running, aborting."));
        delete m_checker; // OnExit() won't be called if we return false
        m_checker = NULL;
        return false;
#endif
    }
    // Allow using environment variables in the file paths in the resources,
    // while keeping the default wxXRC_USE_LOCALE flag.
    // wxXmlResource::Get()->SetFlags(wxXRC_USE_LOCALE | wxXRC_USE_ENVVARS);

#if wxUSE_RIBBON
    // wxXmlResource::Get()->AddHandler(new wxRibbonXmlHandler);
#endif

#if wxUSE_AUI
    wxXmlResource::Get()->AddHandler(new wxAuiXmlHandler);
    wxXmlResource::Get()->AddHandler(new wxAuiToolBarXmlHandler);
#endif
    wxTranslations::Set(new wxTranslations());
    wxTranslations::Get()->SetLoader(new wxResourceTranslationsLoader());
    wxTranslations::Get()->AddCatalog(wxT("kwooca"), wxLANGUAGE_CHINESE_SIMPLIFIED);
    

    // Load all of the XRC files that will be used. You can put everything
    // into one giant XRC file if you wanted, but then they become more
    // diffcult to manage, and harder to reuse in later projects.

    
#ifdef WIN32
    wxString procName = kWookaGetProcessNameWithPid(0);
    wxString currPath = procName.BeforeLast('\\');
    SetCurrentDirectoryA(currPath.mb_str());
#endif

	// kPosPerferenceInit();
	m_locale = NULL;
    // SelectLanguage(wxLANGUAGE_CHINESE_SIMPLIFIED);
    
#ifdef WIN32
	Privilege(TEXT("SeLockMemoryPrivilege"), TRUE);
	Privilege(TEXT("SeIncreaseWorkingSetPrivilege"), TRUE);
	HANDLE hProcess = GetCurrentProcess();
	SIZE_T dwMinWs;
	SIZE_T dwMaxWs;
	SYSTEM_INFO sysInfo;
	GetProcessWorkingSetSize(hProcess, &dwMinWs, &dwMaxWs);
	GetSystemInfo(&sysInfo);

	if (0 == SetProcessWorkingSetSize(GetCurrentProcess(), (SIZE_T)-1, (SIZE_T) -1)) {
		DWORD dwError = GetLastError();
		printf("ERR: %d\n", dwError);
	}
    _CrtSetBreakAlloc(205);
	// _CrtDumpMemoryLeaks();
	_CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF);
	_CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_DEBUG);

#endif


    kWookaSplashScreenFrame* screen = new kWookaSplashScreenFrame();
    screen->Show(true);
    
    return true;
}


void kWookaApp::ShowPreferencesEditor(wxWindow* parent, kWookaProjectInfo* proj)
{
    if ( !m_prefEditor )
    {
        m_prefEditor.reset(new wxPreferencesEditor);
        m_prefEditor->AddPage(new PrefsPageOperator(&proj->appConfigs));
        m_prefEditor->AddPage(new PrefsPageGeneral(&proj->jvmConfig));
        m_prefEditor->AddPage(new PrefsPageMaven(proj));
    }
    
    m_prefEditor->Show(parent);
}

void kWookaApp::DismissPreferencesEditor()
{
    if ( m_prefEditor )
        m_prefEditor->Dismiss();
}


void kWookaApp::SelectLanguage(int lang)
{
    if (m_locale != NULL)
        delete m_locale;
    wxLocale::AddCatalogLookupPathPrefix("lang");
    m_locale = new wxLocale();
    // m_locale->AddCatalog(_T("kwooca"), wxLANGUAGE_DEFAULT);
    m_locale->AddCatalog(_T("kwooca"), wxLANGUAGE_CHINESE_SIMPLIFIED);
    m_locale->Init(lang, wxLOCALE_LOAD_DEFAULT);
}

void kWookaApp::ShowMainFrame() {
    if (m_mainFrame == NULL){
        m_mainFrame = new kWookaFrame();
        m_mainFrame->Show(true);
    }
}

void kWookaApp::OnMainFrameClosed() {
    m_mainFrame = NULL;
}

// --------------------------------------------------------------------------
// LifeNavigator miniframe
// --------------------------------------------------------------------------



#ifdef  WIN32


void Privilege(TCHAR* pszPrivilege, BOOL bEnable)
{
	HANDLE           hToken;
	TOKEN_PRIVILEGES tp;
	BOOL             status;
	DWORD            error;
	LUID			 luid;

	// open process token
	if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
		DisplayError(TEXT("OpenProcessToken"), GetLastError());

	// get the luid
	if (!LookupPrivilegeValue(NULL, pszPrivilege, &luid))
		DisplayError(TEXT("LookupPrivilegeValue"), GetLastError());

	tp.Privileges[0].Luid = luid;
	tp.PrivilegeCount = 1;

	// enable or disable privilege
	if (bEnable)
		tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
	else
		tp.Privileges[0].Attributes = 0;

	// enable or disable privilege
	status = AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES)NULL, 0);

	// It is possible for AdjustTokenPrivileges to return TRUE and still not succeed.
	// So always check for the last error value.
	error = GetLastError();
	if (!status || (error != ERROR_SUCCESS))
		DisplayError(TEXT("AdjustTokenPrivileges"), GetLastError());

	// close the handle
	if (!CloseHandle(hToken))
		DisplayError(TEXT("CloseHandle"), GetLastError());
}

#endif //  WIN32



